#ifndef AVALON_TCPSOCKETREADER_HPP
#define AVALON_TCPSOCKETREADER_HPP
#include "Avalon/IO/Reader.hpp"
#include "Avalon/Network/Network.hpp"

namespace boost {
namespace system {
  class error_code;
}
}

namespace Avalon {
namespace Network {

  /*! \class TcpSocketReader
   *  \brief Reads from a socket.
   */
  class TcpSocketReader : public IO::Reader {
    public:

      virtual ~TcpSocketReader();

      virtual void Read(IO::Buffer* destination,
        Out<Threading::Async<int> > sizeRead);

      virtual void Read(void* destination, int size,
        Out<Threading::Async<int> > sizeRead);

      virtual void Read(IO::Buffer* destination, int size,
        Out<Threading::Async<int> > sizeRead);

    private:
      friend class TcpServerSocket;
      friend class TcpClientSocketChannel;
      friend class TcpSocketConnection;
      boost::shared_ptr<Detail::SocketType> m_socket;
      Threading::Async<int>* m_sizeRead;
      int m_readSize;
      IO::Buffer* m_buffer;
      boost::function<void (const boost::system::error_code&, size_t)>
        m_dataReadSlot;
      boost::function<void (const boost::system::error_code&, size_t)>
        m_bufferReadSlot;
      boost::function<void (const boost::system::error_code&, size_t)>
        m_bufferSizeReadSlot;

      TcpSocketReader(const boost::shared_ptr<Detail::SocketType>& socket);
      void OnDataRead(const boost::system::error_code& error, size_t size);
      void OnBufferRead(const boost::system::error_code& error, size_t size);
  };
}
}

#endif // AVALON_TCPSOCKETREADER_HPP
